Mapy

Column

Column

Mordeh Katan: Mapy

Stejně jako je hrací deska Osadníků z Katanu v nebývalé míře variabilní a tvárná, stále to není nic v porovnání s balíčkem Leaflet, který se používá pro tvorbu map nejen v prostředí jazyka R, ale například i JavaScriptu. Mějte tudíž na paměti, že budete-li na internetu vyhledávat různé příklady práce s Leafletem, nebudete mnohým skriptům příliš rozumět, jelikož budou psány právě v JavaScriptu. My však s tímto programovacím jazykem nepracujeme, a proto i v této poslední lekci zůstaňme věrni pouze R.

Leaflet funguje jako běžný balíček. Z tohoto důvodu budete-li chtít mapy vkládat do R Markdownu či Flexdashboardu, budete muset vždy v příslušném code chunku tento balíček znovu spustit pomocí standardního příkazu library(). Před tím si ho však musíme nejprve nainstalovat.

install.packages("leaflet")

Balíček je nainstalován, můžeme se proto společně pustit do prvního úkolu, ve kterém si zobrazíme hlavní město Prahu.

library(leaflet)

mapa <- leaflet() %>% 
  setView(lng = 14.4378, lat = 50.075539, zoom = 12) %>% addTiles()

mapa

Naše úvodní mapa Prahy se skládá z několika po sobě jdoucích příkazů, jež jsou vzájemně propojeny trubkou, která je při tvorbě map velice užitečná, jelikož nám umožňuje uvádět příkazy v jejich logické posloupnosti.

První krok, který je nezbytný učinit, spočívá v tvorbě nové proměnné mapa <- leaflet(). Prozatím však mapa nemá co ukazovat, proto jí potřebujeme v následujícím kroku zadefinovat místo zobrazení pomocí příkazu setView(lng = -14.4378, lat = 50.075539, zoom = 12), který v sobě ukrývá tři parametry. Prvním z nich je lng, jenž obsahuje údaje o poledníku. Bratrem toho parametru je lat, který značí naopak rovnoběžky (viz longitude a latitude). Třetí parametr zoom určuje přibližení mapy k bodu, který byl souřadnicemi nastaven. Posledním třetím krokem nezbytným k zobrazení základní mapy v Leafletu je příkaz addTiles(), který definuje typ mapového podkladu. Ten je v našem skriptu prázdný. Z tohoto důvodu bude použit nejzákladnější návrh ve formě openstreetmap.org.

Box: Openstreetmap

OpenStreetMap je projekt, jehož cílem je tvorba volně dostupných geografických dat a jejich následná vizualizace do podoby topografických map (např. silniční mapa, turistická mapa, cyklomapa atd.). Pro tvorbu geodat se jako podklad využívají záznamy z přijímačů GPS či jiné zpravidla digitalizované mapy, které jsou licenčně kompatibilní. Projekt byl založen v roce 2004 a využívá kolektivní spolupráce spolu s koncepcí Otevřeného softwaru. Data jsou poskytována pod licencí Open Database License. OpenStreetMap byl inspirován projekty jako je například Wikipedie.

zdroj: Wikipedia.org

Mapových podkladů nalezneme v Leafletu spousty. Podívejme se tedy alespoň na ty nejznámější, mezi které bezesporu patří Esri.WorldImagery nebo Esri.NatGeoWorldMap. K jejich použití nicméně bude nutné upravit příkaz addTiles() na addProviderTiles().

library(leaflet)

mapa <- leaflet() %>% 
  setView(lng = 14.4378, lat = 50.075539, zoom = 12) %>% 
  addProviderTiles("Esri.WorldImagery")

mapa

Esri.NatGeoWorldMap se oproti Esri.WorldImagery a OpenStreetMap liší zejména v tom, že ho nelze volně použít ke komerčním účelům. Na druhé straně je Esri.WorldImagery od roku 2017 součástí OpenStreetMap.

library(leaflet)

mapa <- leaflet() %>% 
  setView(lng = 14.4378, lat = 50.075539, zoom = 12) %>% 
  addProviderTiles("Esri.NatGeoWorldMap")

mapa

V případě, že budeme chtít na mapě zobrazit jedno konkrétní místo a k němu určitý text, použijeme příkaz addPopups(), který definuje souřadnice místa zobrazení určitého popisku.

library(leaflet)

mapa <- leaflet() %>% 
  setView(lng = 14.427778, lat = 50.087222, zoom = 18) %>% 
  addProviderTiles("Esri.WorldImagery") %>%
  addPopups(lng = 14.427778, lat = 50.087222, 
    '<a href="https://cs.wikipedia.org/wiki/Pra%C5%A1n%C3%A1_br%C3%A1na" target="_blank">
    Prašná brána</a>',
    options = popupOptions(closeButton = TRUE))

mapa

Pokud chceme náš text v okně trochu více upravit a dostat jej na více řádků, použijeme následující postup, ve kterém využijeme naše znalosti z HTML. Parametr sep = "<br/>" v rámci příkazu paste() zaručí, že jednotlivé údaje v proměnné obsah budou odděleny vždy novým řádkem.

library(leaflet)

obsah <- paste(sep = "<br/>",
  '<a href="https://cs.wikipedia.org/wiki/Pra%C5%A1n%C3%A1_br%C3%A1na" target="_blank">
  Prašná brána</a>',
  "rok výstavby: 1475",
  "Staré Město, Praha 1")

mapa <- leaflet() %>% 
  setView(lng = 14.427778, lat = 50.087222, zoom = 18) %>% 
  addProviderTiles("Esri.WorldImagery") %>%
  addPopups(lng = 14.427778, lat = 50.087222, obsah,
    options = popupOptions(closeButton = TRUE))

mapa

Jeden odkaz na mapě nás ale příliš neuspokojí. Ukažme si proto, jak lze výše uvedených odkazů vložit do mapy o mnoho více, a to ve formě tzv. pinů. Před tím si však budeme muset nejdříve vytvořit vzorový data frame se vzorkem tří pražských památek. Jako mapový podklad použijeme Esri.WorldStreetMap. Po rozkliknutí jednotlivých pinů se zobrazí text uvedený v proměnné památka.

library(leaflet)

památka <- c("Prašná brána", "Pražský hrad", "Karlův most")
lng <- c(14.427778, 14.401667, 14.411944)
lat <- c(50.087222, 50.091056, 50.086389)
data <- data.frame(památka, lng, lat)

mapa <- leaflet(data) %>% addProviderTiles("Esri.WorldStreetMap") %>%
  addMarkers(~lng, ~lat, popup = data$památka)

mapa

Opusťme matičku Prahu a zaměřme se ve druhé části této lekce na celý svět. Představme si, že sledujeme hodnoty určité proměnné, například kvality městské hromadné dopravy měřené pomocí Sustainable Cities Mobility Index (viz What Are the Main Factors Affecting the Quality of Public Transport in Cities?). Tento index nabývá různých hodnot od nuly do sta, kde vyšší číslo značí vyšší kvalitu dopravy. Naším cílem je vynést hodnoty tohoto indexu do mapy a barevně odlišit tři úrovně (hodnoty vyšší nebo rovno 59 zelená, pod 59 ale více jak 51 žlutá, méně nebo rovno 51 červená). A aby to vše nebylo málo, budeme chtít, aby se po rozkliknutí barevného puntíku města zobrazila samotná hodnota indexu. Databázi si můžete stáhnout níže.

library(leaflet)

data <- read.csv2("C:/Users/jsoln/OneDrive/Desktop/RLANDIO/8.kapitola/Mapa_leaflet.csv")

mapa <- leaflet(data = data) %>%
  addProviderTiles("Esri.NatGeoWorldMap") %>%
  setView(lng = 15.055741, lat = 12.134846, zoom = 2) %>%
  addCircleMarkers(lng = ~lng, 
                   lat = ~lat, 
                   radius = 15,
                   color = ~ifelse(val >= 59, "#38CE23", 
                            ifelse(val > 51 & val < 59, "#FFD900",
                            ifelse(val =< 51, "#FF0000", "#FF0000"))),
                   stroke = FALSE, 
                   fillOpacity = 0.9,
                   popup = ~as.character(name)) 

mapa

Body na mapu jsme přidali pomocí příkazu addCircleMarkers(), ve kterém jsme nejdříve definovali zeměpisnou délku, šířku a přiblížení. Parametrem radius jsme určili velikost jednotlivých puntíků, abychom následně pomocí color stanovili barvy těchto bodů a parametrem fillOpacity jejich průsvitnost. Poslední parametr popup si vzal za úkol určit text zobrazující se po rozkliknutí daného bodu na mapě.

Máte-li zájem se o Leafletu dozvědět mnohem víc, doporučím vám zejména následující stránky. Ty totož obsahují vzevrubné informace o tomto balíčku včetně konkrétních postupů, kterak například vytvořit následující mapu.

cities <- read.csv(textConnection("
City,Lat,Long,Pop
Boston,42.3601,-71.0589,645966
Hartford,41.7627,-72.6743,125017
New York City,40.7127,-74.0059,8406000
Philadelphia,39.9500,-75.1667,1553000
Pittsburgh,40.4397,-79.9764,305841
Providence,41.8236,-71.4222,177994
"))

mapa <- leaflet(cities) %>% addProviderTiles("Esri.WorldStreetMap") %>%
  addCircles(lng = ~Long, lat = ~Lat, weight = 1,
             radius = ~sqrt(Pop) * 30, popup = ~City)

mapa

Další webová stránka, která by vám neměla uniknout, obsahuje podrobný soupis všemožných mapových podkladů včetně jejich ukázek. V případě, že se vám totiž OpenStreetMapy nelíbí, naleznete zde jistě takový styl, se kterým budete spokojeni. Výběr je tu doopravdy široký. Sám za sebe mohu například zmínit podklad zobrazující železniční sítě v jednotlivých zemích světa. Na tomto místě je dobré též zdůraznit, že mapových podkladů můžete v Leafletu současně použít hned několik, jak to lze vidět v posledním skriptu této lekce. V něm bude první mapový podklad tvořit základní mapu a druhý dodá výše zmíněnou železniční síť. A aby toho nebylo málo, dovolil jsem si do skriptu přidat i tři zcela nové příkazy. První z nich se nazývá addMiniMap(), jenž přidává malou mapku do pravého dolního rohu (viz úvod každé kapitoly). Druhý z nich addSearchOSM() přidává vyhledávání měst a vesnic a poslední addFullscreenControl() umožňuje roztáhnutí mapy na celou obrazovku.

library(leaflet)
library(leaflet.extras)


data <- read.csv2("C:/Users/jsoln/OneDrive/Desktop/RLANDIO/8.kapitola/Mapa_leaflet.csv")


mapa <- leaflet(data = data) %>%
  addProviderTiles("OpenStreetMap.Mapnik") %>%
  addProviderTiles("OpenRailwayMap") %>% 
  setView(lng = 15.335125, lat = 49.741807, zoom = 7)  %>%
  addMiniMap(tiles = providers$Esri.WorldStreetMap,
             toggleDisplay = TRUE, minimized = FALSE) %>%
  addSearchOSM() %>%
  addFullscreenControl(position = "topleft")

mapa

Příklady

Příklad 1

Vytvořte mapu, která zobrazí město Brno na mapovém podkladu Esri.WorldImagery, který však bude obsahovat i místopisné údaje (tj. názvy měst, vesnic, silnice atd.).

Příklad 2

Znázorněte na mapě světa s mapovým podkladem Esri.NatGeoWorldMap veškerá hlavní města. Po rozkliknutí jednotlivých měst by se měl zobrazit následující text ve formátu: Prague, country: Czech Republic, ISO CODE: CZ.

Column

Příklady

Column

Column

Příklady: řešení

Příklad 1

Vytvořte mapu, která zobrazí město Brno na mapovém podkladu Esri.WorldImagery, který však bude obsahovat i místopisné údaje (tj. názvy měst, vesnic, silnice atd.).

library(leaflet)

mapa <- leaflet() %>% 
  setView(lng = 16.598914, lat = 49.194289, zoom = 13) %>%
  addProviderTiles("Esri.WorldImagery") %>%
  addProviderTiles("Stamen.TonerHybrid") %>% 
  addPopups(lng = 16.598914, lat = 49.194289, 
            '<center><a href="https://en.wikipedia.org/wiki/Brno" target="_blank">
            Brno</a></center>',
            options = popupOptions(closeButton = TRUE))

mapa

# Souřadnice v decimálním formátu můžete nalézt například tak,
# že půjdete na stránky Wikipedie, kliknete v pravém panelu na 
# souřadnice uvedené ve stupních, což vás přenese na stránky
# GeoHack, kde již tyto informace uvidíte.

# HTML příkaz <center> </center> zarovná text na střed.

Příklad 2

Znázorněte na mapě světa s mapovým podkladem Esri.NatGeoWorldMap veškerá hlavní města. Po rozkliknutí jednotlivých měst se bude zobrazovat následující text ve formátu: Prague, country: Czech Republic, ISO CODE: CZ.

library(readxl)
library(tidyr)

Countries <- read_excel("C:/Users/.../Countries.xlsx")

Countries <- Countries %>%
  unite(Text, c("Město", "Země"), sep = ", country: ")  %>%
  unite(Text, c("Text", "Kód"), sep = ", ISO CODE: ") 

mapa <- leaflet(data = Countries) %>%
  addProviderTiles("Esri.NatGeoWorldMap") %>%
  setView(lng = 15.055741, lat = 12.134846, zoom = 2) %>%
  addMarkers(~lng, ~lat, popup = Countries$Text)

mapa

Column